package com.qq.weixin.mp.api.oauth2.impl;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.hxexp.weixin.common.exception.APIException;
import com.hxexp.weixin.common.httpclient.Json2ObjectHandler;
import com.qq.weixin.constant.APIConstant;
import com.qq.weixin.mp.api.oauth2.Oauth2API;
import com.qq.weixin.mp.api.oauth2.model.WebAccessTokenBean;
import com.qq.weixin.mp.api.oauth2.model.WebUserInfoBean;

/**
 * 微信公众平台网页授权接口实现类
 * @author li.jiang
 *
 */
@Component
public final class Oauth2APIImpl implements Oauth2API {
    private final CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(new PoolingHttpClientConnectionManager()).build();
    @Value("${oauth2_api.access_token.url}")
    private String accessTokenApiUrl;
    @Value("${oauth2_api.userinfo.url}")
    private String userInfoApiUrl;
    /* (non-Javadoc)
     * @see com.hxexp.weixin.api.oauth2.wrapper.Oauth2API#getAccessToken(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public WebAccessTokenBean getAccessToken(String code, String appId, String appSecret) throws APIException {
        String url = String.format("%s?appid=%s&secret=%s&code=%s&grant_type=%s", accessTokenApiUrl, appId, appSecret, code,
                APIConstant.GRANT_TYPE_AUTHORIZATION);
        HttpGet get = new HttpGet(url);
        // 指定对象映射器的属性命名策略为小写加下划线
        PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy s = new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy();
        TypeReference<WebAccessTokenBean> typeReference = new TypeReference<WebAccessTokenBean>() {
        };
        try {
            return httpclient.execute(get, new Json2ObjectHandler<WebAccessTokenBean>(typeReference, s));
        } catch (ClientProtocolException e) {
            throw new APIException(e);
        } catch (IOException e) {
            throw new APIException(e);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.qq.weixin.mp.api.oauth2.Oauth2API#getUserInfo(java.lang.String, java.lang.String)
     */
    @Override
    @CachePut(value = "webUserInfoCache", key = "#openid")
    public WebUserInfoBean getUserInfo(String accesssToken, String openid) throws APIException {
        String url = String.format("%s?access_token=%s&openid=%s&lang=zh_CN", userInfoApiUrl, accesssToken, openid);
        HttpGet get = new HttpGet(url);
        TypeReference<WebUserInfoBean> typeReference = new TypeReference<WebUserInfoBean>() {
        };
        try {
            return httpclient.execute(get, new Json2ObjectHandler<WebUserInfoBean>(typeReference));
        } catch (ClientProtocolException e) {
            throw new APIException(e);
        } catch (IOException e) {
            throw new APIException(e);
        }
    }

}
